﻿using System;
using System.Drawing;
using System.Runtime.InteropServices;
using ESRI.ArcGIS.ADF.BaseClasses;
using ESRI.ArcGIS.ADF.CATIDs;
using ESRI.ArcGIS.Controls;
using ESRI.ArcGIS.Framework;
using ESRI.ArcGIS.ArcMapUI;
using ESRI.ArcGIS.Carto;
using ESRI.ArcGIS.Geodatabase;
using ESRI.ArcGIS.esriSystem;

//using EngineDemo_CSharp.General;
using System.Windows.Forms;
//using ESRI.ArcGIS.GeoDatabaseUI;
using ESRI.ArcGIS.SystemUI;
using ESRI.ArcGIS.Geometry;
using System.Collections;

using DIWAGIS.Tools;
//using EngineDemo_CSharp.General;

namespace DIWAGIS.EditorTools
{
    /// <summary>
    /// Command that works in ArcMap/Map/PageLayout
    /// </summary>
    [Guid("a970174b-7e47-4859-96ea-670d68f9a446")]
    [ClassInterface(ClassInterfaceType.None)]
    [ProgId("DIWAGIS.EditorTools.AddT")]
    public sealed class AddT : BaseCommand
    {
        #region COM Registration Function(s)
        [ComRegisterFunction()]
        [ComVisible(false)]
        static void RegisterFunction(Type registerType)
        {
            // Required for ArcGIS Component Category Registrar support
            ArcGISCategoryRegistration(registerType);

            //
            // TODO: Add any COM registration code here
            //
        }

        [ComUnregisterFunction()]
        [ComVisible(false)]
        static void UnregisterFunction(Type registerType)
        {
            // Required for ArcGIS Component Category Registrar support
            ArcGISCategoryUnregistration(registerType);

            //
            // TODO: Add any COM unregistration code here
            //
        }

        #region ArcGIS Component Category Registrar generated code
        /// <summary>
        /// Required method for ArcGIS Component Category registration -
        /// Do not modify the contents of this method with the code editor.
        /// </summary>
        private static void ArcGISCategoryRegistration(Type registerType)
        {
            string regKey = string.Format("HKEY_CLASSES_ROOT\\CLSID\\{{{0}}}", registerType.GUID);
            MxCommands.Register(regKey);
            ControlsCommands.Register(regKey);
        }
        /// <summary>
        /// Required method for ArcGIS Component Category unregistration -
        /// Do not modify the contents of this method with the code editor.
        /// </summary>
        private static void ArcGISCategoryUnregistration(Type registerType)
        {
            string regKey = string.Format("HKEY_CLASSES_ROOT\\CLSID\\{{{0}}}", registerType.GUID);
            MxCommands.Unregister(regKey);
            ControlsCommands.Unregister(regKey);
        }

        #endregion
        #endregion

        private IHookHelper m_hookHelper = null;
     
        private string _pointLayerName;
        private string _matchLineLayerName;
        private string _targetLineLayerName;
        private string _pointFieldNameToCalc;
        private string _matchFieldNameForCalc;
        private string _prefix;
        private int _targetLineSubcode;
        private string _targetLineSubcodeField;// bo sung
        private string _targetLineFieldName;
        private string _targetLineValue;
        private bool _deleteExistingLines;
        private string _targetPointLayerName;
        private int _targetPointSubcode;
        private string _targetPointIsNeededField;
        private double _targetPointDistance;
        private bool _targetPointDistanceIsPercent;
        private bool _useDualWhenTwoSelected;
        private double _maxDualDistanceForTwoSelected;
        private bool _useDualWhenNearby;
        private double _maxDualDistanceForNearby;
        private double _tolerenceForDelete;
        private double _doglegDistance;
        private bool _startAtMain;
        private bool _squareDualLines;
        private IMap pMap;
        private IMapControl3 m_mapControl;
        //private frm_Main frmMain;
        //private IEngineEditor _editor;
        //private IEngineEditor m_editor;
        private IEngineEditor _editor = new EngineEditorClass();
        //private IEngineEditor _editor1;
        private IEngineEditor _editor1 = new EngineEditorClass();
        //private IEditor _editor;
        // private IEditor3 _editor1;
        //private IEngineEditor _editor1;
        public AddT()
        {
            //
            // TODO: Define values for the public properties
            //
            //base.m_category = ""; //localizable text
            //base.m_caption = "";  //localizable text 
            //base.m_message = "This should work in ArcMap/MapControl/PageLayoutControl";  //localizable text
            //base.m_toolTip = "";  //localizable text
            //base.m_name = "";   //unique id, non-localizable (e.g. "MyCategory_MyCommand")

            //try
            //{
            //    //
            //    // TODO: change bitmap name if necessary
            //    //
            //    string bitmapResourceName = GetType().Name + ".bmp";
            //    base.m_bitmap = new Bitmap(GetType(), bitmapResourceName);
            //}
            //catch (Exception ex)
            //{
            //    System.Diagnostics.Trace.WriteLine(ex.Message, "Invalid Bitmap");
            //}

            base.m_caption = "Vẽ ống nhánh nối trụ cứu hỏa đến ống chính";
            base.m_message = "Vẽ ống nhánh nối trụ cứu hỏa đến ống chính";
            base.m_toolTip = "Vẽ ống nhánh nối trụ cứu hỏa đến ống chính";
            base.m_name = "WaterUtilityTools_AddWaterServiceLines";
            GetConfigSettings();
            try
            {
                //
                // TODO: change bitmap name if necessary
                //
                string bitmapResourceName = GetType().Name + ".png";
                base.m_bitmap = new Bitmap(GetType(), bitmapResourceName);
            }
            catch (Exception ex)
            {
                System.Diagnostics.Trace.WriteLine(ex.Message, "Invalid Bitmap");
            }
        }

        #region Overridden Class Methods

        /// <summary>
        /// Occurs when this command is created
        /// </summary>
        /// <param name="hook">Instance of the application</param>

        public void GetConfigSettings()
        {
            ConfigUtil cu = new ConfigUtil();

           
                _pointLayerName = cu.GetConfigValue("AddHydrantLaterals_Point_FeaturceClass", "wTruCuuHoa");// Tru hong
                _matchLineLayerName = cu.GetConfigValue("AddHydrantLaterals_Main_FeatureClass", "wOngChinh");
                _targetLineLayerName = cu.GetConfigValue("AddHydrantLaterals_LateralLine_FeatureClass", "wOngNhanh");
                _pointFieldNameToCalc = cu.GetConfigValue("AddHydrantLaterals_FieldInPointToPopulateFromMain", "LOCDESC");
                _matchFieldNameForCalc = cu.GetConfigValue("AddHydrantLaterals_FieldInMainToCopy", "OBJECTID");
                _prefix = cu.GetConfigValue("AddHydrantLaterals_FieldInService_AddPrefix", "PipeID:");
                _targetLineSubcode = cu.GetConfigValue("AddHydrantLaterals_LateralLine_Subcode", -1);
                _targetLineFieldName = cu.GetConfigValue("AddHydrantLaterals_LateralLine_FieldToPopulate", "LINETYPE");
                _targetLineValue = cu.GetConfigValue("AddHydrantLaterals_LateralLine_ValueToPopulate", "Hydrant");
                _deleteExistingLines = cu.GetConfigValue("AddHydrantLaterals_DeleteExistingLines", true);
                _targetPointLayerName = cu.GetConfigValue("AddHydrantLaterals_PointAlong_FeatureClass", "wSystemValve");
                _targetPointSubcode = cu.GetConfigValue("AddHydrantLaterals_PointAlong_Subtype", -1);
                _targetPointIsNeededField = cu.GetConfigValue("AddHydrantLaterals_PointAlong_IsNeeded_Field", "HYDRFLAG");
                _targetPointDistance = cu.GetConfigValue("AddHydrantLaterals_PointAlong_Distance", 50);
                _targetPointDistanceIsPercent = cu.GetConfigValue("AddHydrantLaterals_PointAlong_DistanceIsPercent", true);
                _useDualWhenTwoSelected = cu.GetConfigValue("AddHydrantLaterals_Dual_When_Two_Selected", false);
                _useDualWhenNearby = cu.GetConfigValue("AddHydrantLaterals_Dual_When_Nearby", false);
                _maxDualDistanceForTwoSelected = cu.GetConfigValue("AddHydrantLaterals_Dual_Max_Distance_When_Two_Selected", 0);
                _maxDualDistanceForNearby = cu.GetConfigValue("AddHydrantLaterals_Dual_Max_Distance_When_Nearby", 0);
                _squareDualLines = cu.GetConfigValue("AddHydrantLaterals_Dual_Option_Make_Square", false);
                _tolerenceForDelete = cu.GetConfigValue("AddHydrantLaterals_TolerenceForDelete", 0.5);
                _doglegDistance = cu.GetConfigValue("AddHydrantLaterals_Hook_DoglegDistance", 0);
                _startAtMain = cu.GetConfigValue("AddHydrantLaterals_Direction_StartAtMain", true);
         
        }
        public override void OnCreate(object hook)
        {
            //if (hook == null)
            //    return;

            //try
            //{
            //    m_hookHelper = new HookHelperClass();
            //    m_hookHelper.Hook = hook;
            //    if (m_hookHelper.ActiveView == null)
            //        m_hookHelper = null;
            //}
            //catch
            //{
            //    m_hookHelper = null;
            //}

            //if (m_hookHelper == null)
            //    base.m_enabled = false;
            //else
            //    base.m_enabled = true;

            // TODO:  Add other initialization code

            if (hook != null)
            {

                //Check for ArcMap
                if (hook is IMxApplication)
                {

                    m_hookHelper = new HookHelperClass();
                    m_hookHelper.Hook = hook;
                    IApplication app = hook as IApplication;
                    pMap = m_hookHelper.FocusMap;
                    //Get the editor.
                    UID editorUID = new UIDClass();
                    editorUID.Value = "esriControls.ControlsEditingEditTool";
                    IEngineEditor _editor = app.FindExtensionByCLSID(editorUID) as IEngineEditor;
                    IEngineEditor _editor1 = app.FindExtensionByCLSID(editorUID) as IEngineEditor;


                    if (_editor != null)
                    {
                        base.m_enabled = true;
                        return;
                    }
                }
            }

            // On Create disable this command if ArcMap editor was not found.  
            //_editor = null;
            //_editor1 = null;
            base.m_enabled = true;
            return;

        }

        /// <summary>
        /// Occurs when this command is clicked
        /// </summary>
        public override void OnClick()
        {
            // TODO: Add AddT.OnClick implementation
            AddLaterals();
        }

        #endregion
         public override bool Enabled
        {
            get
            {
                //Enable this command when editing with some features selected.
                if ((_editor != null) &&
                    (_editor.EditState == esriEngineEditState.esriEngineStateEditing) &&
                    (_editor.SelectionCount > 0))
                    return true;
                else
                    //return false;
                    return true;
            }
        }
     
       
      
       

        public void   AddLaterals()
        {
            try
            {
                //Get edit session
                IEngineEditor editor = _editor;
              
                if (editor.EditState != esriEngineEditState.esriEngineStateEditing)
                {
                    MessageBox.Show("Phải bắt đầu hiệu chỉnh.", this.Tooltip);
                    return;
                }
                //MessageBox.Show(_targetPointDistance.ToString());
                //MessageBox.Show(_targetPointLayerName.ToString());
                //MessageBox.Show(_targetLineLayerName.ToString());
                //Change mouse cursor to wait - automatically changes back (ArcGIS Desktop only)
                //IMouseCursor appCursor = new MouseCursorClass();
                //appCursor.SetCursor(2);   
        
                //IApplication app = editor.Parent;
                //IMxDocument mxdoc = (IMxDocument)app.Document;
               
                //IMap map = generalVariable.mapControl.Map ;
                IFeature lineFeature = null;

                //Find required layers
              
                IFeatureLayer pointFLayer = FindFeatureLayer("Trụ cứu hỏa");// dong ho
              
                IFeatureLayer matchLineFLayer = FindFeatureLayer("Ống chính");// ong phan phoi
               
                IFeatureLayer targetLineFLayer = FindFeatureLayer("Ống nhánh");//ong nganh can ve

                //Report any problems before exiting
                if (pointFLayer == null)
                {
                    MessageBox.Show("Layer representing connection points was not found.  Configuration indicated feature class name: '" + _pointLayerName + "'.", this.Tooltip);
                    return;
                }
                if (matchLineFLayer == null)
                {
                    MessageBox.Show("Layer representing mains was not found.  Configuration indicated feature class name: '" + _matchLineLayerName + "'.", this.Tooltip);
                    return;
                }
                if (targetLineFLayer == null)
                {
                    MessageBox.Show("Layer representing target lines was not found.  Configuration indicated feature class name: '" + _targetLineLayerName + "'.", this.Tooltip);
                    return;
                }


                //Find Optional layer (used to add new cleanout along lateral)
                
                //IFeatureLayer targetPointFLayer = GetEditableFeatureLayerbyFCName(_targetPointLayerName);// ve them van
                // thay the
                IFeatureLayer targetPointFLayer = FindFeatureLayer("Van khách hàng");

               // MessageBox.Show("1");
                //Verify that some points are selected
                IFeatureSelection pointFeatureSelection = (IFeatureSelection)pointFLayer;
                if (pointFeatureSelection.SelectionSet.Count == 0)
                    return;

                //Confirm that target layer is editable and is a line layer
                IEngineEditLayers eLayers = (IEngineEditLayers)editor;
                if (!(eLayers.IsEditable(targetLineFLayer)) | (targetLineFLayer.FeatureClass.ShapeType != ESRI.ArcGIS.Geometry.esriGeometryType.esriGeometryPolyline))
                    return;

                //Confirm the other layers are the correct shape type
                if (pointFLayer.FeatureClass.ShapeType != ESRI.ArcGIS.Geometry.esriGeometryType.esriGeometryPoint | matchLineFLayer.FeatureClass.ShapeType != ESRI.ArcGIS.Geometry.esriGeometryType.esriGeometryPolyline)
                    return;

                //Confirm that the two line layers are different Feature classes
                if ((matchLineFLayer.FeatureClass.CLSID == targetLineFLayer.FeatureClass.CLSID) && (matchLineFLayer.FeatureClass.AliasName == targetLineFLayer.FeatureClass.AliasName))
                {
                    MessageBox.Show("Mains and target lines muct be in different feature classes.", "Unable to add lines.");
                    return;
                }
                IFeatureSelection matchLineFSel = matchLineFLayer as IFeatureSelection;

                //Verify subtype is valid for target line 
                if (targetLineFLayer != null)
                {
                    // MessageBox.Show("1");
                    ISubtypes targetLineSubtypes = targetLineFLayer.FeatureClass as ISubtypes;

                    // MessageBox.Show("2");

                    string targetLineSubtypeName = _targetLineSubcodeField;// targetLineSubtypes.get_SubtypeName(_targetLineSubcode);// "CoOng";

                    //MessageBox.Show(_targetLineSubcodeField);
                    if ((targetLineSubtypes == null) || (!targetLineSubtypes.HasSubtype) || (_targetLineSubcode < 0) || (String.IsNullOrEmpty(targetLineSubtypeName)))
                        _targetLineSubcode = -1;

                }
                else
                    _targetLineSubcode = -1;


                //Verify subtype is valid for target point 
                if (targetPointFLayer != null)
                {

                    ISubtypes targetPointSubtypes = targetPointFLayer.FeatureClass as ISubtypes;
                    string targetPointSubtypeName = targetPointSubtypes.get_SubtypeName(_targetPointSubcode);
                    if ((targetPointSubtypes == null) || (!targetPointSubtypes.HasSubtype) || (_targetPointSubcode < 0) || (String.IsNullOrEmpty(targetPointSubtypeName)))
                        _targetPointSubcode = -1;

                }
                else
                    _targetPointSubcode = -1;


                ICursor pointCursor;

                IFeature pointFeature;
                int total = pointFeatureSelection.SelectionSet.Count;
                int i = 0;
                
                //ProgressBar
                //ESRI.ArcGIS.Framework.IProgressDialogFactory progressDialogFactory = new ESRI.ArcGIS.Framework.ProgressDialogFactoryClass();
                //MessageBox.Show("1113");
                //// Create a CancelTracker
                ESRI.ArcGIS.esriSystem.ITrackCancel trackCancel = new ESRI.ArcGIS.Display.CancelTrackerClass();
                //MessageBox.Show("13");
                //// Set the properties of the Step Progressor
                //System.Int32 int32_hWnd = generalVariable.mapControl.hWnd;
                //ESRI.ArcGIS.esriSystem.IStepProgressor stepProgressor = progressDialogFactory.Create(trackCancel, int32_hWnd);
                //stepProgressor.MinRange = 0;
                //stepProgressor.MaxRange = total;
                //stepProgressor.StepValue = 1;
                //stepProgressor.Message = "Tạo ống ngánh";
                //// Create the ProgressDialog. This automatically displays the dialog
                //ESRI.ArcGIS.Framework.IProgressDialog2 progressDialog = (ESRI.ArcGIS.Framework.IProgressDialog2)stepProgressor; // Explict Cast
                //MessageBox.Show("14");
                //// Set the properties of the ProgressDialog
                //progressDialog.CancelEnabled = true;
                //progressDialog.Description = "Tạo ống ngánh " + i.ToString() + " of " + total.ToString() + ".";
                //progressDialog.Title = "Tạo ống ngánh";
                //progressDialog.Animation = ESRI.ArcGIS.Framework.esriProgressAnimationTypes.esriProgressGlobe;
              
                // Create an edit operation enabling undo/redo
                editor.StartOperation();
                try
                {

                    IPoint fromPoint, selPt1, selPt2;
                    ILine distanceLine;
                    object Missing = Type.Missing;
                    IEnvelope env;
                    IEnumIDs selIds;
                    IFeature pointFeature2;
                    int featOID1, featOID2, nearbyCount;
                    ISelectionSet2 sel = pointFeatureSelection.SelectionSet as ISelectionSet2;
                    sel.Update(null, false, out pointCursor);
                    ArrayList completedOIDArrayList = new ArrayList();

                    while ((pointFeature = (IFeature)pointCursor.NextRow()) != null)
                    {
                        i += 1;
                        //Update progress bar
                       // progressDialog.Description = "Tạo ống ngánh " + i.ToString() + " of " + total.ToString() + "." + Environment.NewLine +
                        //  "Đang xử lý đối tượng: " + pointFeature.OID;
                        //stepProgressor.Step();
                        //ESRI.ArcGIS.esriSystem.IStatusBar statusBar =generalVariable.mapControl.s //app.StatusBar;
                        //statusBar.set_Message(0, i.ToString());

                        //Check if the cancel button was pressed. If so, stop process
                        bool boolean_Continue = trackCancel.Continue();
                        if (!boolean_Continue)
                        {
                            break;
                        }

                        //Get the "from" point for new line (start from selected point)
                        fromPoint = pointFeature.ShapeCopy as IPoint;
                      
                        //Get selected line 
                        if (matchLineFSel.SelectionSet.Count == 1)
                        {
                           
                            lineFeature = matchLineFLayer.FeatureClass.GetFeature(matchLineFSel.SelectionSet.IDs.Next());
                            
                        }
                       
                        //Create new feature(s)
                        {
                            env = new EnvelopeClass();

                            //Dual Laterals When Two Selected
                            if (total == 2 && _useDualWhenTwoSelected)
                            {

                                //Obtain both starting points
                                selIds = sel.IDs;
                                selIds.Reset();
                                featOID1 = selIds.Next();
                                featOID2 = selIds.Next();
                                pointFeature2 = pointFLayer.FeatureClass.GetFeature(featOID2);
                                selPt1 = pointFeature.ShapeCopy as IPoint;
                                selPt2 = pointFeature2.ShapeCopy as IPoint;
                              
                                //Measure distance
                                distanceLine = new LineClass();
                                distanceLine.PutCoords(selPt1, selPt2);
                                if (distanceLine.Length <= _maxDualDistanceForTwoSelected)
                                {
                                    // bo sung
                                 
                                    CreateSingle(pointFeature, matchLineFLayer, lineFeature, targetLineFLayer, targetPointFLayer);
                                 
                                    CreateSingle(pointFeature2, matchLineFLayer, lineFeature, targetLineFLayer, targetPointFLayer);
                                    // bo   
                                    //CreateDual(pointFeature, pointFeature2, distanceLine, matchLineFLayer, lineFeature, targetLineFLayer, targetPointFLayer);
                                    break;
                                }
                                //Create two single laterals if the duals are not created
                                else
                                {

                                    CreateSingle(pointFeature, matchLineFLayer, lineFeature, targetLineFLayer, targetPointFLayer);
                                    
                                    CreateSingle(pointFeature2, matchLineFLayer, lineFeature, targetLineFLayer, targetPointFLayer);
                                    break;
                                }
                            }

                            //Dual Laterals when Nearby
                            else if ((total != 1) & _useDualWhenNearby)
                            {

                              
                                
                                //Check that this feature has not already been completed                               
                                
                                if (completedOIDArrayList.Contains(pointFeature.OID))
                                    continue;

                                selPt1 = pointFeature.ShapeCopy as IPoint;
                                nearbyCount = 0;
                                pointFeature2 = null;

                                //Determine if extactly one other point is within the specified max distance
                                ITopologicalOperator topoOp = selPt1 as ITopologicalOperator;
                                IPolygon poly = topoOp.Buffer(_maxDualDistanceForNearby / 2) as IPolygon;
                                ISpatialFilter sFilter = new SpatialFilterClass();
                                sFilter.Geometry = poly;
                                sFilter.GeometryField = pointFLayer.FeatureClass.ShapeFieldName;
                                sFilter.SpatialRel = esriSpatialRelEnum.esriSpatialRelIntersects;

                                IFeatureCursor lineCursor = pointFLayer.FeatureClass.Search(sFilter, false);
                                IFeature testPointFeature;
                                while ((testPointFeature = lineCursor.NextFeature()) != null)
                                {
                                    if (testPointFeature.OID != pointFeature.OID)
                                    {
                                        //Check that this nearby feature has not already been completed
                                        if (!completedOIDArrayList.Contains(pointFeature.OID))
                                        {
                                            pointFeature2 = testPointFeature;
                                            nearbyCount += 1;
                                        }
                                    }
                                    if (nearbyCount > 1)
                                        break;
                                }
                               
                                if (nearbyCount == 1)
                                {
                                    selPt2 = pointFeature2.ShapeCopy as IPoint;

                                    //Measure distance
                                    distanceLine = new LineClass();
                                    distanceLine.PutCoords(selPt1, selPt2);
                                    // bo
                                    //CreateDual(pointFeature, pointFeature2, distanceLine, matchLineFLayer, lineFeature, targetLineFLayer, targetPointFLayer);
                                    // bo sung
                                    CreateSingle(pointFeature2, matchLineFLayer, lineFeature, targetLineFLayer, targetPointFLayer);
                                    CreateSingle(pointFeature, matchLineFLayer, lineFeature, targetLineFLayer, targetPointFLayer);
                                    //Add 2nd OID to completed list
                                    completedOIDArrayList.Add(pointFeature2.OID);
                                }

                                //Create a single lateral if 1 nearby not found
                                else
                                {
                                    CreateSingle(pointFeature, matchLineFLayer, lineFeature, targetLineFLayer, targetPointFLayer);
                                }

                            }
                            //Single Laterals
                            else
                            {
                                CreateSingle(pointFeature, matchLineFLayer, lineFeature, targetLineFLayer, targetPointFLayer);

                            }
                        }


                    }
                    Marshal.ReleaseComObject(pointCursor);

                }
                catch (Exception ex)
                {
                    editor.AbortOperation();
                    editor.StopOperation("Tạo ống ngánh");
                    MessageBox.Show(ex.Message, ex.Source);

                    // Cleanup
                    //if (progressDialog != null)
                    //    progressDialog.HideDialog();
                    //return;
                }

                // Cleanup
                //progressDialog.HideDialog();


                // Stop the edit operation 
                editor.StopOperation("Tạo ống ngánh");

                IActiveView activeView = DIWAGIS.Modules.generalVariable.mapControl.Map as IActiveView;
                activeView.Refresh();
            }

            catch (Exception ex)
            {
                MessageBox.Show(ex.Message, ex.Source);
                return;
            }
        }

        #region Helper methods
        private void CreateSingle(IFeature pointFeature, IFeatureLayer matchLineFLayer, IFeature lineFeature, IFeatureLayer targetLineFLayer, IFeatureLayer targetPointFLayer)
        {
            // Get closest main to point1
            IFeatureSelection matchLineFSel = (IFeatureSelection)matchLineFLayer;
            IPoint thisPoint = (IPoint)pointFeature.Shape;
            IPoint turnPoint, toPoint;
            if (matchLineFSel.SelectionSet.Count != 1)
                lineFeature = GetNearestFeature(thisPoint, matchLineFLayer.FeatureClass, 500);

            if (lineFeature != null)
            {
                //Delete any existing lateral lines at this location
                if (_deleteExistingLines)
                {
                    DeleteExistingFeatures(pointFeature, targetLineFLayer, targetPointFLayer);
                }

                //If requested, store pipe id in the point
                StorePipeIdOnPointFeature(lineFeature, pointFeature);

                //Determine To and Turn Points
                ICurve mainCurve = lineFeature.ShapeCopy as ICurve;
                CreateToAndTurnPoints(mainCurve, thisPoint, out turnPoint, out toPoint);

                //Create the new line
                IPolyline newPolyLine = CreatePolylineFromPoints(thisPoint, toPoint, turnPoint);

                if (newPolyLine.Length > 0)
                {
                    if (_startAtMain)
                        newPolyLine.ReverseOrientation();

                    CreateLineFeature(targetLineFLayer, newPolyLine);

                    //Optionally, create new point along line
                    AddPointAlongLine(newPolyLine as ICurve, targetPointFLayer);
                }
            }
        }
        private void CreateDual(IFeature pointFeature, IFeature pointFeature2, ILine distanceLine, IFeatureLayer matchLineFLayer, IFeature lineFeature, IFeatureLayer targetLineFLayer, IFeatureLayer targetPointFLayer)
        {
            IPoint point = (IPoint)pointFeature.Shape;
            IPoint point2 = (IPoint)pointFeature2.Shape;
            IPoint turnPoint, toPoint, joinPoint, sqPoint1, sqPoint2;

            //Determine mid point
            IPoint midPoint = new PointClass();
            distanceLine.QueryPoint(esriSegmentExtension.esriNoExtension, 0.5, true, midPoint);

            // Get closest main to midpoint (if a single main was not selected)
            IFeatureSelection matchLineFSel = (IFeatureSelection)matchLineFLayer;
            if (matchLineFSel.SelectionSet.Count != 1)
                lineFeature = GetNearestFeature(midPoint, matchLineFLayer.FeatureClass, 500);

            if (lineFeature != null)
            {
                //Delete any existing lateral lines at these locations
                if (_deleteExistingLines)
                {
                    DeleteExistingFeatures(pointFeature, targetLineFLayer, targetPointFLayer);
                    DeleteExistingFeatures(pointFeature2, targetLineFLayer, targetPointFLayer);
                }


                //If requested, store pipe id in the point
                StorePipeIdOnPointFeature(lineFeature, pointFeature);
                StorePipeIdOnPointFeature(lineFeature, pointFeature2);

                //Determine To and Turn Points (and possible square points)
                ICurve mainCurve = lineFeature.ShapeCopy as ICurve;
                CreateToAndTurnPointsDual(mainCurve, midPoint, distanceLine, out toPoint, out turnPoint, out joinPoint, out  sqPoint1, out  sqPoint2);
                //if (turnPoint == null || turnPoint.IsEmpty)
                //{
                //  turnPoint = toPoint;
                //}

                IPolyline polyline;

                //Create the new base line (possibly hooked)
                polyline = CreatePolylineFromPoints(joinPoint, turnPoint, toPoint);
                if (_startAtMain)
                    polyline.ReverseOrientation();
                CreateLineFeature(targetLineFLayer, polyline);

                if (_squareDualLines)
                {
                    //Create Arm 1
                    polyline = CreatePolylineFromPoints(point, sqPoint1, joinPoint);
                    if (_startAtMain)
                        polyline.ReverseOrientation();
                    CreateLineFeature(targetLineFLayer, polyline);
                    AddPointAlongLine(polyline, targetPointFLayer);
                    //Create Arm 2
                    polyline = CreatePolylineFromPoints(point2, sqPoint2, joinPoint);
                    if (_startAtMain)
                        polyline.ReverseOrientation();
                    CreateLineFeature(targetLineFLayer, polyline);
                    AddPointAlongLine(polyline, targetPointFLayer);
                }
                else
                {
                    //Create branch 1
                    polyline = CreatePolylineFromPoints(point, joinPoint);
                    if (_startAtMain)
                        polyline.ReverseOrientation();
                    CreateLineFeature(targetLineFLayer, polyline);
                    AddPointAlongLine(polyline, targetPointFLayer);

                    //Create branch 2
                    polyline = CreatePolylineFromPoints(point2, joinPoint);
                    if (_startAtMain)
                        polyline.ReverseOrientation();
                    CreateLineFeature(targetLineFLayer, polyline);
                    AddPointAlongLine(polyline, targetPointFLayer);
                }
            }
        }
        private void StorePipeIdOnPointFeature(IFeature lineFeature, IFeature pointFeature)
        {
            int pointFieldToCalc = pointFeature.Fields.FindField(_pointFieldNameToCalc);
            int matchFieldForCalc = lineFeature.Fields.FindField(_matchFieldNameForCalc);
            if (pointFieldToCalc > -1 && matchFieldForCalc > -1)
            {
                if (pointFeature.Fields.get_Field(pointFieldToCalc).Type == esriFieldType.esriFieldTypeString)
                    pointFeature.set_Value(pointFieldToCalc, _prefix + lineFeature.get_Value(matchFieldForCalc).ToString());
                else
                    pointFeature.set_Value(pointFieldToCalc, lineFeature.get_Value(matchFieldForCalc));
                pointFeature.Store();
            }
        }
        private void CreateLineFeature(IFeatureLayer targetLineFLayer, IPolyline newPolyLine)
        {
            try
            {

                ISpatialReference sr = _editor.Map.SpatialReference;
                ISpatialReferenceResolution srr = sr as ISpatialReferenceResolution;
                IUnitConverter uc = new UnitConverterClass();
                uc.ConvertUnits(0.0001, esriUnits.esriMeters, _editor.Map.MapUnits);

                if (newPolyLine.Length > uc.ConvertUnits(0.0001, esriUnits.esriMeters, _editor.Map.MapUnits))
                {
                    IFeature newFeature = targetLineFLayer.FeatureClass.CreateFeature();
                    IFeatureClass newfeaturecalss = targetLineFLayer.FeatureClass;
                    ISubtypes newsubtype = (ISubtypes)newfeaturecalss;
                    //MessageBox.Show( newsubtype.get_DefaultValue, this.Tooltip);
                    newFeature.Shape = newPolyLine;

                    IRowSubtypes rowSubtype = newFeature as IRowSubtypes;
                    if (_targetLineSubcode > -1)
                    {
                        rowSubtype.SubtypeCode = _targetLineSubcode;
                    }
                    rowSubtype.InitDefaultValues();

                    //If avaiable, store specified value in the new line 

                    //int targetFieldToCalc = targetLineFLayer.FeatureClass.FindField(_targetLineFieldName);
                    //if (targetFieldToCalc > -1)
                    //    if (newFeature.Fields.get_Field(targetFieldToCalc).Type == esriFieldType.esriFieldTypeString)
                    //        newFeature.set_Value(targetFieldToCalc, _targetLineValue.ToString());
                    //    else

                    //newFeature.set_Value( targetFieldToCalc, _targetLineValue);

                    newFeature.set_Value(newFeature.Fields.FindField("CoOng"), 25);

                    //IEditTemplate editTemplate = _editor1.CurrentTemplate;
                    //editTemplate.SetDefaultValues(newFeature);
                    newFeature.Store();
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show("Vui lòng chọn loại ống ngánh", this.Tooltip);

            }
        }
        private IPolyline CreatePolylineFromPoints(params IPoint[] points)
        {
            object Missing = Type.Missing;
            IPolyline newPolyLine = new PolylineClass();
            IPointCollection newPointColl = (IPointCollection)newPolyLine;
            foreach (IPoint pnt in points)
            {
                if (pnt != null && !pnt.IsEmpty)
                    newPointColl.AddPoint(pnt, ref Missing, ref Missing);
            }
            if (newPointColl.PointCount < 2)
                newPolyLine = new PolylineClass();

            return newPolyLine;

        }
        private void CreateToAndTurnPoints(ICurve mainCurve, IPoint joinPoint, out IPoint toPoint, out IPoint turnPoint)
        {
            IPoint closestPointOnMain = new PointClass();
            IProximityOperator lineProxOp = mainCurve as IProximityOperator;
            closestPointOnMain = lineProxOp.ReturnNearestPoint(joinPoint, esriSegmentExtension.esriNoExtension);

            //Create temp line along main
            ILine tempLine = new LineClass();
            tempLine.FromPoint = closestPointOnMain;
            tempLine.ToPoint = mainCurve.ToPoint;

            //Create temp line to main
            ILine tempLine2 = new LineClass();
            tempLine2.FromPoint = closestPointOnMain;
            tempLine2.ToPoint = joinPoint;

            //Adjust distance if needed
            double dist = _doglegDistance;
            if (tempLine.Length < tempLine2.Length && tempLine.Length < dist)
            {
                dist = tempLine.Length / 2;
            }
            else if (tempLine2.Length < tempLine.Length && tempLine2.Length < dist)
            {
                dist = tempLine2.Length / 2;
            }

            //Create the "to" point for new line - tap location on main
            IPoint tempPt1 = new PointClass();
            IConstructPoint constTempPt1 = (IConstructPoint)tempPt1;
            constTempPt1.ConstructAlong(tempLine, esriSegmentExtension.esriNoExtension, dist, false);
            toPoint = (IPoint)constTempPt1;

            //Create dogleg (turn) point for new line if needed
            if (_doglegDistance > 0)
            {
                IPoint tempPt2 = new PointClass();
                IConstructPoint constTempPt2 = (IConstructPoint)tempPt2;
                constTempPt2.ConstructAlong(tempLine2, esriSegmentExtension.esriNoExtension, dist, false);
                turnPoint = (IPoint)constTempPt2;
            }
            else
                turnPoint = null;

        }
        private void CreateToAndTurnPointsDual(ICurve mainCurve, IPoint midPoint, ILine distanceLine, out IPoint toPoint, out IPoint turnPoint, out IPoint joinPoint, out IPoint sqPoint1, out IPoint sqPoint2)
        {
            sqPoint1 = new PointClass();
            sqPoint2 = new PointClass();

            //Determine nearest point on main 
            IPoint closestPointOnMain = new PointClass();
            IProximityOperator lineProxOp = mainCurve as IProximityOperator;
            closestPointOnMain = lineProxOp.ReturnNearestPoint(midPoint, esriSegmentExtension.esriNoExtension);

            //Create temp line along main
            ILine tempLine = new LineClass();
            tempLine.FromPoint = closestPointOnMain;
            tempLine.ToPoint = mainCurve.ToPoint;

            //Create temp line to main
            ILine tempLine2 = new LineClass();
            tempLine2.FromPoint = closestPointOnMain;
            tempLine2.ToPoint = midPoint;

            //Adjust distance if needed
            double dist = _doglegDistance;
            if (tempLine.Length < tempLine2.Length && tempLine.Length < dist)
                dist = tempLine.Length / 2;
            else if (tempLine2.Length < tempLine.Length && tempLine2.Length < dist)
                dist = tempLine2.Length / 2;


            //Create the "to" point for new line - tap location on main
            IPoint tempPt1 = new PointClass();
            IConstructPoint constTempPt1 = (IConstructPoint)tempPt1;
            constTempPt1.ConstructAlong(tempLine, esriSegmentExtension.esriNoExtension, dist, false);
            toPoint = (IPoint)constTempPt1;

            //Create the dogleg "turn" point for new line if needed
            if (_doglegDistance > 0)
            {
                IPoint tempPt2 = new PointClass();
                IConstructPoint constTempPt2 = (IConstructPoint)tempPt2;
                constTempPt2.ConstructAlong(tempLine2, esriSegmentExtension.esriNoExtension, dist, false);
                turnPoint = (IPoint)constTempPt2;
            }
            else
                turnPoint = null;

            //Determine Join Point
            joinPoint = new PointClass();
            ILine verticalLine = new LineClass() as ILine;
            verticalLine.FromPoint = midPoint;
            if (turnPoint != null)
                verticalLine.ToPoint = turnPoint;
            else
                verticalLine.ToPoint = closestPointOnMain;
            if (verticalLine.Length > distanceLine.Length)
                dist = distanceLine.Length / 2;
            else if (verticalLine.Length > 10)
                dist = verticalLine.Length / 2;
            else
                return;
            verticalLine.QueryPoint(esriSegmentExtension.esriNoExtension, dist, false, joinPoint);

            if (_squareDualLines)
            {
                //Create squared turn points
                IConstructPoint conSqPoint1 = sqPoint1 as IConstructPoint;
                IConstructPoint conSqPoint2 = sqPoint2 as IConstructPoint;

                conSqPoint1.ConstructAngleIntersection(distanceLine.FromPoint, verticalLine.Angle, joinPoint, tempLine.Angle);
                conSqPoint2.ConstructAngleIntersection(distanceLine.ToPoint, verticalLine.Angle, joinPoint, tempLine.Angle);
            }
        }
        private IFeature GetNearestFeature(IPoint sourcePointFeature, IFeatureClass searchFeatureClass, int maxDistance)
        {
            IFeature nearestFeature = null;

            ITopologicalOperator topoOp = sourcePointFeature as ITopologicalOperator;
            IPolygon poly = topoOp.Buffer(maxDistance) as IPolygon;
            ISpatialFilter sFilter = new SpatialFilterClass();
            sFilter.Geometry = poly;
            sFilter.GeometryField = searchFeatureClass.ShapeFieldName;
            sFilter.SpatialRel = esriSpatialRelEnum.esriSpatialRelIntersects;

            IFeatureCursor lineCursor = searchFeatureClass.Search(sFilter, false);
            IFeature lineFeature = lineCursor.NextFeature();
            IProximityOperator proxOp;
            double distance;
            double lastDistance = maxDistance;
            while (!(lineFeature == null))
            {
                proxOp = (IProximityOperator)sourcePointFeature;
                distance = proxOp.ReturnDistance(lineFeature.Shape);
                if (distance < lastDistance)
                {
                    nearestFeature = lineFeature;
                    lastDistance = distance;
                }
                lineFeature = lineCursor.NextFeature();
            }
            proxOp = null; lineFeature = null;
            Marshal.ReleaseComObject(lineCursor);

            return nearestFeature;
        }
        private void DeleteFeaturesAtPoint(IFeatureLayer targetLineFLayer, IPoint point, IFeatureLayer targetPointFLayer)
        {

            ITopologicalOperator topoOp = point as ITopologicalOperator;
            IPolygon poly = topoOp.Buffer(_tolerenceForDelete) as IPolygon;
            ISpatialFilter sFilter = new SpatialFilterClass();
            sFilter.Geometry = poly;
            sFilter.GeometryField = targetLineFLayer.FeatureClass.ShapeFieldName;
            sFilter.SpatialRel = esriSpatialRelEnum.esriSpatialRelIntersects;

            INetworkClass netClass = targetLineFLayer.FeatureClass as INetworkClass;
            IFeatureClass orphanFC = netClass.GeometricNetwork.OrphanJunctionFeatureClass;
            INetworkFeature netFeature;
            IFeatureCursor fCursor = targetLineFLayer.FeatureClass.Search(sFilter, false);
            IFeature feature;
            IPolyline line;
            IEdgeFeature edgeFeature;
            ISimpleJunctionFeature toJunctionFeature = null;
            ISimpleJunctionFeature fromJunctionFeature = null;
            while ((feature = fCursor.NextFeature()) != null)
            {
                //Find connecting junctions
                netFeature = feature as INetworkFeature;
                if (netFeature != null)
                {
                    edgeFeature = netFeature as IEdgeFeature;
                    if (edgeFeature != null)
                    {
                        toJunctionFeature = edgeFeature.ToJunctionFeature as ISimpleJunctionFeature;
                        fromJunctionFeature = edgeFeature.ToJunctionFeature as ISimpleJunctionFeature;
                    }
                }

                //If subtypes are specified for the new lateral lines, delete only existing laterals with that subtype
                ISubtypes subt = feature as ISubtypes;
                line = feature.ShapeCopy as IPolyline;
                if (_targetLineSubcode > -1 && subt != null)
                {
                    int? thisSubtype = feature.get_Value(subt.SubtypeFieldIndex) as int?;
                    if (thisSubtype != null && thisSubtype == _targetLineSubcode)
                    {
                        feature.Delete();

                        DeleteTargetPoints(targetPointFLayer.FeatureClass, line);
                        DeleteExisitingJunction(toJunctionFeature, targetLineFLayer);
                        DeleteOrphanJunctions(orphanFC, line);
                    }
                }

                //Otherwise, just delete each feature
                else
                {
                    feature.Delete();
                    DeleteTargetPoints(targetPointFLayer.FeatureClass, line);
                    DeleteExisitingJunction(toJunctionFeature, targetLineFLayer);
                    DeleteOrphanJunctions(orphanFC, line);
                }
            }
            feature = null;
            Marshal.ReleaseComObject(fCursor);

        }
        private void DeleteExistingFeatures(IFeature pointFeature, IFeatureLayer targetLineFLayer, IFeatureLayer targetPointFLayer)
        {
            //Halt delete if the selected point feature is not a simple junction feature or has no connected edges
            ISimpleJunctionFeature junc = pointFeature as ISimpleJunctionFeature;
            if (junc == null || junc.EdgeFeatureCount != 1)
                return;

            IEdgeFeature edge; IFeature edgeFeature; ISimpleJunctionFeature oppositeJunctionFeature;
            bool flowAway = true;
            INetworkClass netClass = targetLineFLayer.FeatureClass as INetworkClass;
            IFeatureClass orphanFC = netClass.GeometricNetwork.OrphanJunctionFeatureClass;
            IPolyline line;

            //Return the connected edge (with correct subtype if used)
            //Return null if more than one found
            edge = junc.get_EdgeFeature(0);

            if (edge != null)
            {
                edgeFeature = edge as IFeature;
                if (flowAway)
                    oppositeJunctionFeature = edge.ToJunctionFeature as ISimpleJunctionFeature;
                else
                    oppositeJunctionFeature = edge.FromJunctionFeature as ISimpleJunctionFeature;

                line = edgeFeature.ShapeCopy as IPolyline;
                edgeFeature.Delete();
                if (targetPointFLayer != null && targetPointFLayer.Valid)
                    DeleteTargetPoints(targetPointFLayer.FeatureClass, line);
                DeleteExisitingJunction(oppositeJunctionFeature, targetLineFLayer);
                DeleteOrphanJunctions(orphanFC, line);
            }
            //bool deleteFlag = false;
            //ISubtypes subt = edgeFeature as ISubtypes;
            //if (_targetLineSubcode < 0 || subt == null)
            //  deleteFlag = true;
            //else
            //{
            //  //If subtypes are specified for the new lateral lines, delete only existing laterals with that subtype
            //  int? thisSubtype = edgeFeature.get_Value(subt.SubtypeFieldIndex) as int?;
            //  if (thisSubtype != null && thisSubtype == _targetLineSubcode)
            //    deleteFlag = true;
            //}

        }
        private void DeleteExisitingJunction(ISimpleJunctionFeature juncFeature, IFeatureLayer targetLineFLayer)
        {
            if (juncFeature != null)
            {
                IFeature thisJuction = juncFeature as IFeature;

                //If this junction connects to one lateral line delete the junction and the line
                if (juncFeature.EdgeFeatureCount == 1)
                {
                    IFeature edgeFeat = juncFeature.get_EdgeFeature(0) as IFeature;
                    IEdgeFeature edge = edgeFeat as IEdgeFeature;
                    IFeature toJuncFeat = edge.ToJunctionFeature as IFeature;
                    ISimpleJunctionFeature toJunc = toJuncFeat as ISimpleJunctionFeature;

                    if (edgeFeat.Class.ObjectClassID == targetLineFLayer.FeatureClass.FeatureClassID)
                        edgeFeat.Delete();

                    if (DeleteNeeded(toJunc))
                        toJuncFeat.Delete();
                }

                //If this junction connects two edges of the same line, delete the junction
                if (DeleteNeeded(juncFeature))
                    thisJuction.Delete();
            }
        }
        private bool DeleteNeeded(ISimpleJunctionFeature juncFeature)
        {
            if (juncFeature.EdgeFeatureCount == 2)
            {
                IFeature feat1 = juncFeature.get_EdgeFeature(0) as IFeature;
                IFeature feat2 = juncFeature.get_EdgeFeature(1) as IFeature;
                if (feat1.OID == feat2.OID && feat1.Class.ObjectClassID == feat2.Class.ObjectClassID)
                    return true;
            }
            return false;
        }
        private void DeleteTargetPoints(IFeatureClass targetFC, IPolyline line)
        {
            if (targetFC != null && line != null)
            {
                //Buffer the line 
                ITopologicalOperator topoOpLine = line as ITopologicalOperator;
                IPolygon poly2 = topoOpLine.Buffer(_tolerenceForDelete) as IPolygon;
                ISpatialFilter sFilter2 = new SpatialFilterClass();
                sFilter2.Geometry = poly2;
                sFilter2.GeometryField = targetFC.ShapeFieldName;
                sFilter2.SpatialRel = esriSpatialRelEnum.esriSpatialRelIntersects;
                IFeatureCursor fCursor2 = targetFC.Search(sFilter2, false);
                IFeature feature2;
                while ((feature2 = fCursor2.NextFeature()) != null)
                {
                    feature2.Delete();
                }
                Marshal.ReleaseComObject(fCursor2);
            }
        }
        private void DeleteOrphanJunctions(IFeatureClass orphanFC, ICurve curve)
        {
            if (orphanFC != null && curve != null)
            {
                //Buffer the line 
                ITopologicalOperator topoOpLine = curve as ITopologicalOperator;
                IPolygon poly2 = topoOpLine.Buffer(_tolerenceForDelete) as IPolygon;
                ISpatialFilter sFilter2 = new SpatialFilterClass();
                sFilter2.Geometry = poly2;
                sFilter2.GeometryField = orphanFC.ShapeFieldName;
                sFilter2.SpatialRel = esriSpatialRelEnum.esriSpatialRelIntersects;
                IFeatureCursor fCursor2 = orphanFC.Search(sFilter2, false);
                IFeature feature2;
                while ((feature2 = fCursor2.NextFeature()) != null)
                {
                    ISimpleJunctionFeature juncfeat = feature2 as ISimpleJunctionFeature;
                    if (juncfeat != null)
                    {
                        if (juncfeat.EdgeFeatureCount == 0)
                            feature2.Delete();
                        else if (juncfeat.EdgeFeatureCount == 2)
                        {
                            IRow row1 = juncfeat.get_EdgeFeature(0) as IRow;
                            IRow row2 = juncfeat.get_EdgeFeature(1) as IRow;
                            if (row1.OID == row2.OID)
                                feature2.Delete();
                        }
                    }

                }
                Marshal.ReleaseComObject(fCursor2);
            }
        }
        private void AddPointAlongLine(ICurve curve, IFeatureLayer pointFLayer)
        {
            double workingDist = _targetPointDistance;
           
            if (curve != null && pointFLayer != null)
            {
                IPoint point = new PointClass();
                try
                {
                    if (_targetPointDistanceIsPercent)
                    {
                        if (workingDist > 1 && workingDist < 100)
                            workingDist = _targetPointDistance / 100;
                        curve.QueryPoint(esriSegmentExtension.esriNoExtension, workingDist, true, point);
                    }
                    else if (curve.Length > _targetPointDistance)
                        curve.QueryPoint(esriSegmentExtension.esriNoExtension, _targetPointDistance, false, point);
                    else
                        curve.QueryPoint(esriSegmentExtension.esriNoExtension, 0.5, true, point);
                }
                catch { }
                if (!(point.IsEmpty))
                {
                    IFeature newFeature = pointFLayer.FeatureClass.CreateFeature();
                    newFeature.Shape = point;

                    IRowSubtypes pointRowSubtype = newFeature as IRowSubtypes;
                    if (_targetPointSubcode > -1)
                        pointRowSubtype.SubtypeCode = _targetPointSubcode;
                    pointRowSubtype.InitDefaultValues();
                    try
                    {
                        newFeature.Store();
                    }
                    catch
                    {
                    }
                }
            }
        }
        private IFeatureLayer FindFeatureLayer(string name)
        {

            IFeatureLayer foundLayer = null;
            IDataset dataset = null;
            ILayer layer = null;
           // layer = generalVariable.mapControl.get_Layer(i);
            //MessageBox.Show(map.LayerCount.ToString, this.Tooltip);
            for (int i = 0; i < DIWAGIS.Modules.generalVariable.mapControl.LayerCount ; i++)
            {
                //ILayer layer = (ILayer)generalVariable.mapControl.Map.get_Layer(i);
               
                layer = DIWAGIS.Modules.generalVariable.mapControl.get_Layer(i);
                if (layer.Name == name)
                {
                    //MessageBox.Show(generalVariable.mapControl.get_Layer(i).Name.ToString());
                    foundLayer = (IFeatureLayer)layer;
                    break;
                }
            }


            //
         


            //

            return foundLayer;
        }

        // bo sung ham khac thay the
        private IFeatureLayer GetEditableFeatureLayerbyFCName(string featureClassName)
        {
            IEngineEditor editor = _editor;
            IEngineEditLayers eLayers = editor as IEngineEditLayers;

            UID geoFeatureLayerID = new UIDClass();
            geoFeatureLayerID.Value = "{E156D7E5-22AF-11D3-9F99-00C04F6BC78E}";
            IEnumLayer enumLayer = DIWAGIS.Modules.generalVariable.mapControl.Map.get_Layers(((ESRI.ArcGIS.esriSystem.UID)geoFeatureLayerID), true);

            // Step through each geofeature layer in the map
            enumLayer.Reset();
            IFeatureLayer fLayer = enumLayer.Next() as IFeatureLayer;
            IDataset dataset;
            char[] c = new char[] { '.' };

            while (fLayer != null)
            {
                if (fLayer.Valid && eLayers.IsEditable(fLayer))
                {
                    dataset = fLayer as IDataset;
                    string[] nameParts = dataset.BrowseName.Split(c);
                    string testName = nameParts[nameParts.Length - 1];

                    if (testName.ToLower() == featureClassName.ToLower())
                    {
                        return fLayer; ;
                    }
                }
                fLayer = enumLayer.Next() as IFeatureLayer;
            }
            return null;

        }
        #endregion
    }
}
